using System;
using System.Text;
using UnityEngine;

public class NetPacketUDP : NetConnUDP.IReader
{
    public static readonly int HeaderByteSize = 2;

    private int sendBufferSize = 0;
    private int readBufferSize = 0;

    private byte[] sendBuffer = null;
    private NetworkStream sendStream = null;

    public delegate void OnPacket(byte[] data,int offset,int size);

    public event OnPacket onPacket;

    public NetPacketUDP(int readBufferSize,int sendBufferSize)
    {
        this.readBufferSize = readBufferSize;
        this.sendBufferSize = sendBufferSize;

        sendBuffer = new byte[sendBufferSize];
        sendStream = new NetworkStream(sendBuffer);
    }

    public void BeginSendStream()
    {
        sendStream.Position = HeaderByteSize;
    }

    public NetworkInputStream GetSendStream()
    {
        return new NetworkInputStream(sendStream);
    }

    public void WriteToSendStream(byte[] buffer, int offset, int count)
    {
        sendStream.Write(buffer, offset, count);
    }

    public byte[] FlushSendStream(ref int retCount)
    {
        if(sendStream.Position < HeaderByteSize)
        {
            throw new Exception("position < HeaderByteSize");
        }

        retCount = (int)sendStream.Position;

        ulong packageSize = (ulong)(sendStream.Position - HeaderByteSize);

        Tools.ULongBytes(packageSize, sendBuffer, 0, HeaderByteSize, false);

        sendStream.Position = 0;

        return sendBuffer;
    }

    public byte[] PackageSendBuffer(byte[] buffer, int offset, int count,ref int retCount)
    {
        if(null == buffer || (count + offset > buffer.Length) || (count + HeaderByteSize > sendBufferSize))
        {
            Debug.LogError("PackageSendBuffer failed! offset:" + offset + " count:" + count);
            return null;
        }

        retCount = HeaderByteSize + count;

        Tools.ULongBytes((ulong)count, sendBuffer,0,HeaderByteSize,false);

        Array.Copy(buffer,offset,sendBuffer,HeaderByteSize,count);

        return sendBuffer;
    }

    public bool OnRead(byte[] buffer)
    {
        if(buffer.Length < HeaderByteSize || buffer.Length > readBufferSize)
        {
            return false;
        }

        int packageLength = (int)Tools.Bytes2ULong(buffer,0,HeaderByteSize,false);
        if(packageLength + HeaderByteSize > buffer.Length)
        {
            return false;
        }

        if(onPacket != null)
        {
            onPacket(buffer,HeaderByteSize,packageLength);
        }

        return true;
    }
}